package com.aacar.service.impl;

import com.aacar.utils.*;
import com.aacar.vo.UserInfoVo;
import com.alipay.config.AlipayConfig;
import com.aacar.dao.*;
import com.aacar.dto.UserIntegralPayDto;
import com.aacar.entity.*;
import com.aacar.interceptor.TranFailException;
import com.aacar.service.OrderPayService;
import com.aacar.service.SeqService;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.tencent.WXPay;
import com.tencent.common.Configure;
import com.tencent.common.Signature;
import com.tencent.common.XMLParser;
import com.tencent.protocol.pay_protocol.UnifiedOrderReqData;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Repository;
import push.PushUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Repository("orderPayService")
public class OrderPayServiceImpl implements OrderPayService {

	private Log logger = LogFactory.getLog(OrderPayServiceImpl.class);

	@Resource
	private OrderDao orderDao;

	@Resource
	private OrderDemandDao orderDemandDao;

	@Resource
	private OrderPayDao orderPayDao;

	@Resource
	private CouponDao couponDao;

	@Resource
	private WasherDao washerDao;

	@Resource
	private SeqService seqService;

	@Resource
	private UserIntegralPayDao userIntegralPayDao;

	@Resource
	private MemberDao memberDao;


	/**
	 * 用户积分支付 生成支付宝支串
	 * @param userIntegralPayDto
	 * @return
	 * @throws TranFailException
	 */
	@Override
	public String genAlipayPayStrOrderUIP(UserIntegralPayDto userIntegralPayDto) throws TranFailException {

		//金额处理
		String totalAmount = "";
		if("sit".equals(CommonStaticPath.systemConf)){
			totalAmount = "0.01";
		}else{
			totalAmount = String.valueOf(userIntegralPayDto.getIntegral());
		}

		//生成订单号
		String uipOrderNo = "UIP"+seqService.getSeqNoFromMem("0", 1)
				+"-"+userIntegralPayDto.getRechargeType()
		        +"-"+userIntegralPayDto.getUserId();


		String payStr = ""; //支付宝支付串

		//实例化客户端
		AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
				AlipayConfig.app_id, AlipayConfig.private_key, "json", AlipayConfig.input_charset, AlipayConfig.ali_public_key, "RSA2");
		//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
		//SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		model.setBody(AlipayConfig.body_uip);
		model.setSubject(AlipayConfig.subject_uip);
		model.setOutTradeNo(uipOrderNo);
		model.setTimeoutExpress(AlipayConfig.it_b_pay);
		model.setTotalAmount(totalAmount);
		model.setProductCode("QUICK_MSECURITY_PAY");
		request.setBizModel(model);
		request.setNotifyUrl(AlipayConfig.notify_url_order_uip);

		try {
			AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
			payStr = response.getBody();
			logger.info(" #### 生成支付串 ："+payStr);
		} catch (AlipayApiException e) {
			e.printStackTrace();

		}

		//插入会员充值支付订单

		UserIntegralPay  userIntegralPay = new UserIntegralPay();
		userIntegralPay.setUipOrderNo(uipOrderNo);
		userIntegralPay.setThirdPayStr(payStr);
		userIntegralPay.setPayType("1");
		userIntegralPay.setPayStatus("PA01");
		userIntegralPay.setOrderAmount(Double.valueOf(totalAmount));
		userIntegralPay.setPayAmount(Double.valueOf(totalAmount));
		userIntegralPay.setIntegral(Double.valueOf(totalAmount));
		userIntegralPay.setUserId(userIntegralPayDto.getUserId());
		userIntegralPay.setRechargeType(userIntegralPayDto.getRechargeType());
		userIntegralPayDao.save(userIntegralPay);

		return payStr;
	}

	@Override
	public String genWeiXinPayStrOrderUIP(UserIntegralPayDto userIntegralPayDto, String remoteAddr) throws Exception {

		//金额处理
		int totalAmount = 0;
		if("sit".equals(CommonStaticPath.systemConf)){
			totalAmount = (int)(0.01 * 100);
		}else{
			totalAmount = (int)(userIntegralPayDto.getIntegral()*100);
		}

		//生成订单号
		String uipOrderNo = "UIP"+seqService.getSeqNoFromMem("0", 1)
				+"-"+userIntegralPayDto.getRechargeType()
				+"-"+userIntegralPayDto.getUserId();



		String deviceInfo = "APP"; //设备号
		String spBillCreateIP =remoteAddr;//终端IP
		String timeStart = getTimeStr(-1); //交易起始时间 (订单生成时间)
		String timeExpire = getTimeStr(1); //交易结束时间  (订单失效时间-最短失效时间间隔必须大于5分钟)
		String goodsTag = null; //商品标记 ，代金券或立减优惠功能的参数
		String product_id = null;//商品ID
		String limit_pay = null;
		String notify_url = Configure.notify_url_order_uip; //接收微信支付异步通知回调地址
		String trade_type = "APP";//交易类型

		//微信统一下单
		UnifiedOrderReqData unifiedOrderReqData = new UnifiedOrderReqData(Configure.body_uip,uipOrderNo,totalAmount,deviceInfo,spBillCreateIP,timeStart,
				timeExpire,goodsTag,product_id,limit_pay,"",notify_url,trade_type);

		//订单响应串
		String orderResStr = WXPay.requestUnifiedOrderService(unifiedOrderReqData);
		logger.info("**********weixin orderResStr:"+orderResStr);

		Map<String,Object> resultResp = XMLParser.getMapFromXML(orderResStr);
		if(!"SUCCESS".equals(resultResp.get("return_code"))){
			//微信统一下单失败
			throw new TranFailException(ErrorCodeConsField.ERROR_MSG_41004, Pphconfig.getContextProperty(ErrorCodeConsField.ERROR_MSG_41004));
		}

		String prepayId = (String)resultResp.get("prepay_id");
		String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
		String nonceStr = UUID.randomUUID().toString();

		String resultStr = toResult(timeStamp, nonceStr, prepayId);

		//插入会员充值支付订单
		UserIntegralPay  userIntegralPay = new UserIntegralPay();
		userIntegralPay.setUipOrderNo(uipOrderNo);
		userIntegralPay.setThirdPayStr(resultStr);
		userIntegralPay.setPayType("2");
		userIntegralPay.setPayStatus("PA01");
		userIntegralPay.setOrderAmount(Double.valueOf(totalAmount));
		userIntegralPay.setPayAmount(Double.valueOf(totalAmount));
		userIntegralPay.setIntegral(Double.valueOf(totalAmount));
		userIntegralPay.setUserId(userIntegralPayDto.getUserId());
		userIntegralPay.setRechargeType(userIntegralPayDto.getRechargeType());
		userIntegralPayDao.save(userIntegralPay);


		return resultStr;
	}

	/**
	 * 积分充值 异步回调处理
	 * @param converRequestParamMap
	 */
	@Override
	public void payCallBackOrderUIP(Map converRequestParamMap) {


		Date now = DateUtil.getNowDate();
		String uipOrderNo = converRequestParamMap.get("out_trade_no").toString();

		//查询支付订单状态 如果不是待支付 直接return
		UserIntegralPay userIntegralPay =  userIntegralPayDao.getUserIntegralPay(uipOrderNo);
		if(userIntegralPay==null){
			logger.info("######################## 支付回调 payCallBackOrderUIP return");
			return;
		}else{
			if(!"PA01".equals(userIntegralPay.getPayStatus())){
				logger.info("######################## 支付回调 payCallBackOrderUIP 处理 payStatus:"+userIntegralPay.getPayStatus());
				logger.info("######################## return");
				return;
			}
		}

		String rechargeType = uipOrderNo.split("-")[1];
		String userId = uipOrderNo.split("-")[2];
		double totalAmount = 0;
		if("sit".equals(CommonStaticPath.systemConf)){
			totalAmount = 200;
		}else{
			totalAmount = Double.valueOf(converRequestParamMap.get("total_amount").toString());
		}
		logger.info("######################## systemConf:"+CommonStaticPath.systemConf);
		logger.info("######################## totalAmount:"+totalAmount);


		totalAmount = 200;

		//会员充值订单
		UserIntegralPay userIntegralPayParam = new UserIntegralPay();
		userIntegralPayParam.setThirdPayCallBackStr(JSONObject.toJSONString(converRequestParamMap));
		userIntegralPayParam.setThirdTradeNo(converRequestParamMap.get("trade_no").toString());
		userIntegralPayParam.setThirdPayCallBackTime(DateUtil.convertStringToDate(DateUtil.defaultPattern2,converRequestParamMap.get("notify_time").toString()));
		userIntegralPayParam.setBuyerThirdPayNo(converRequestParamMap.get("buyer_logon_id").toString());

		userIntegralPayParam.setPayStatus("PA02");//支付状态(PA01-待支付，PA02-已支付 ,PA03-已取消)
		userIntegralPayParam.setPaySubStatus("PA0201");

		userIntegralPayParam.setUipOrderNo(uipOrderNo);
		userIntegralPayDao.update(userIntegralPayParam);

		//修改 会员积分 修改会员等级
		if ("1".equals(rechargeType)){
			Member member = new Member();
			member.setMemberId(Long.valueOf(userId));
			member.setIntegral(MathUtil.disposeAmount(-totalAmount));
			member.setRankId("2");
			member.setRankName("银牌会员");
			memberDao.updateMember(member);

			//推送
			Member memParam2 = new Member();
			memParam2.setMemberId(Long.valueOf(userId));
			UserInfoVo userInfoVo = memberDao.getUserInfo(memParam2);
			PushUtils.sendAndroidAndIOSUnicast(userInfoVo.getDeviceType(),userInfoVo.getDeviceTokens(),"您已充值200积分成功", "");


		}


		//插入会员积分记录
		Map mapParam = new HashMap();
		mapParam.put("orderNo", uipOrderNo);
		mapParam.put("type", "1");
		mapParam.put("amount", totalAmount);
		mapParam.put("createTime", now);
		mapParam.put("userId", userId);
		userIntegralPayDao.saveRecods(mapParam);



	}


    private void checkOrderPay(OrderPay orderPayRes, OrderPay orderPayParam) throws TranFailException{

		//校验用户orderNo和UserId
		if(orderPayRes==null||orderPayRes.getUserId()!=orderPayParam.getUserId()){
			throw new TranFailException(ErrorCodeConsField.ERROR_MSG_41001, Pphconfig.getContextProperty(ErrorCodeConsField.ERROR_MSG_41001));
		}

		//校验订单是否为待支付状态


        //校验提交的支付金额和表里的支付金额是否一致


	}


	/**
	 * 用户订单支付 生成支付宝串
	 * @param orderPayParam
	 * @return
	 * @throws TranFailException
	 */
	@Override
	public String genAlipayPayStrOrder(OrderPay orderPayParam) throws TranFailException{
		OrderPay orderPayRes = orderPayDao.getOrderPay("PA"+orderPayParam.getOrderNo()+"-1");
		checkOrderPay(orderPayRes, orderPayParam);

		//金额处理
		String totalAmount = "";
		if("sit".equals(CommonStaticPath.systemConf)){
			totalAmount = "0.01";
		}else{
			totalAmount = String.valueOf(orderPayRes.getPayAmount());
		}

		String payStr = ""; //支付宝支付串


		//实例化客户端
		AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
				AlipayConfig.app_id, AlipayConfig.private_key, "json", AlipayConfig.input_charset, AlipayConfig.ali_public_key, "RSA2");
		//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		model.setBody(AlipayConfig.body);
		model.setSubject(AlipayConfig.subject);
		model.setOutTradeNo(orderPayRes.getPayOrderNo());
		model.setTimeoutExpress(AlipayConfig.it_b_pay);
		model.setTotalAmount(totalAmount);
		model.setProductCode("QUICK_MSECURITY_PAY");
		request.setBizModel(model);
		request.setNotifyUrl(AlipayConfig.notify_url_order);

		try {
			//这里和普通的接口调用不同，使用的是sdkExecute
			AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
			payStr = response.getBody();
			logger.info(" #### 生成支付串 ："+payStr);
		} catch (AlipayApiException e) {
			e.printStackTrace();

		}


		//更新支付订单表
		orderPayParam.setPayOrderNo(orderPayRes.getPayOrderNo());
		orderPayParam.setPayType("1");//支付宝
		orderPayParam.setThirdPayStr(payStr);
		orderPayParam.setModifyTime(DateUtil.getNowDate());

		orderPayDao.update(orderPayParam);


		return payStr;
	}

	@Override
	public String genAlipayPayStrBUOrder(OrderPay orderPay) throws TranFailException {
		return null;
	}

	@Override
	public void payCallBackOrder(Map converRequestParamMap) {
		Date now = DateUtil.getNowDate();

		String payOrderNo = converRequestParamMap.get("out_trade_no").toString();
		String orderNo = payOrderNo.split("-")[0].replaceAll("PA", "");


		//查询支付订单如果不是待支付 直接return
		OrderPay orderPayRes = orderPayDao.getOrderPay(payOrderNo);
		if(orderPayRes==null){
			logger.info("######################## 支付回调 payCallBackOrder return");
			return;
		}else{
			if(!"PA01".equals(orderPayRes.getPayStatus())){
				logger.info("######################## 支付回调 payCallBackOrder 处理 payStatus:"+orderPayRes.getPayStatus());
				logger.info("######################## return");
				return;
			}
		}


		//更新支付订单
		OrderPay orderPay = new OrderPay();
		orderPay.setThirdPayCallBackStr(JSONObject.toJSONString(converRequestParamMap));
		orderPay.setThirdTradeNo(converRequestParamMap.get("trade_no").toString());
		orderPay.setThirdPayCallBackTime(DateUtil.convertStringToDate(DateUtil.defaultPattern2,converRequestParamMap.get("notify_time").toString()));
		orderPay.setBuyerThirdPayNo(converRequestParamMap.get("buyer_logon_id").toString());

		orderPay.setPayStatus("PA02");//支付状态(PA01-待支付，PA02-已支付 ,PA03-已取消)
		orderPay.setPaySubStatus("PA0201");



		orderPay.setPayOrderNo(payOrderNo);
		int res = orderPayDao.update(orderPay);

		if(res==1){

			//更新主订单
			Order order = new Order();
			order.setOrderStatus("R02");
			order.setOrderStatusName("等待接单");
			order.setOrderSubStatus("R02");
			order.setOrderNo(orderNo);
			order.setModifyTime(now);
			orderDao.update(order);
			logger.info("######################## 更新主订单");

			//更新需求订单
			OrderDemand orderDemand = new OrderDemand();
			orderDemand.setDemandStatus("DE02");//需求状态（DE01-已提交, DE02-待匹配, DE03-已匹配，DE04-已取消)
			orderDemand.setDemandSubStatus("DE02");//需求子状态（DE01-已提交, DE02-待匹配, DE0301-系统匹配, DE0302-人工匹配, DE0401-客户取消，DE0402-系统人工取消，DE0403-系统自动取消)
			orderDemand.setOrderNo(orderNo);
			orderDemand.setModifyTime(now);
			orderDemandDao.update(orderDemand);
			logger.info("######################## 更新需求订单");



//
//			//向洗车工派单
//			List<WasherVo> washUserList = washerDao.getWashUserList(new Washer());
//			for(WasherVo washer:washUserList){
//				SendOrder sendOrder = new SendOrder();
//				sendOrder.setOrderNo(orderNo);
//				sendOrder.setUserId(orderPayRes.getUserId());
//				sendOrder.setSendOrderType("1");//1-自动派单
//				sendOrder.setWashUserId(Long.valueOf(washer.getPid()));
//				sendOrder.setSendOrderTime(now);
//				//查询是否派单
//				SendOrder sendOrderRes = orderPayDao.getSendOrder(sendOrder);
//				if (sendOrderRes==null) {
//					orderPayDao.saveSendOrder(sendOrder);
//				}
//			}
//			logger.info("######################## 向洗车工派单");


			//推送
			logger.info("######################## orderPayRes.getUserId():"+orderPayRes);
			Member memParam2 = new Member();
			memParam2.setMemberId(orderPayRes.getUserId());
			UserInfoVo userInfoVo = memberDao.getUserInfo(memParam2);
			PushUtils.sendAndroidAndIOSUnicast(userInfoVo.getDeviceType(),userInfoVo.getDeviceTokens(),"您尾号为"+orderNo.substring(16)+"的订单(已支付)", orderNo);


		}
	}

	@Override
	public void payCallBackBUOrder(Map converRequestParamMap) {

	}

	@Override
	public String genWeixinPayStr(OrderPay orderPayParam, String remoteAddr) throws Exception{


		String payOrderNo = "PA"+orderPayParam.getOrderNo()+"-1";
		OrderPay orderPayRes = orderPayDao.getOrderPay(payOrderNo);
		checkOrderPay(orderPayRes, orderPayParam);


		//金额处理
		int totalAmount = 0;
		if("sit".equals(CommonStaticPath.systemConf)){
			totalAmount = (int)(0.01 * 100);
		}else{
			totalAmount = (int)(orderPayRes.getPayAmount()*100);
		}

		String deviceInfo = "APP"; //设备号
		String spBillCreateIP =remoteAddr;//终端IP
		String timeStart = getTimeStr(-1); //交易起始时间 (订单生成时间)
		String timeExpire = getTimeStr(1); //交易结束时间  (订单失效时间-最短失效时间间隔必须大于5分钟)
		String goodsTag = null; //商品标记 ，代金券或立减优惠功能的参数
		String product_id = null;//商品ID
		String limit_pay = null;
		String notify_url = Configure.notify_url_order; //接收微信支付异步通知回调地址
		String trade_type = "APP";//交易类型

		//微信统一下单
		UnifiedOrderReqData unifiedOrderReqData = new UnifiedOrderReqData(Configure.body,payOrderNo,totalAmount,deviceInfo,spBillCreateIP,timeStart,
				timeExpire,goodsTag,product_id,limit_pay,"",notify_url,trade_type);

		//订单响应串
		String orderResStr = WXPay.requestUnifiedOrderService(unifiedOrderReqData);
		logger.info("**********weixin orderResStr:"+orderResStr);

		Map<String,Object> resultResp = XMLParser.getMapFromXML(orderResStr);
		if(!"SUCCESS".equals(resultResp.get("return_code"))){
			//微信统一下单失败
			throw new TranFailException(ErrorCodeConsField.ERROR_MSG_41004, Pphconfig.getContextProperty(ErrorCodeConsField.ERROR_MSG_41004));
		}

		String prepayId = (String)resultResp.get("prepay_id");
		String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
		String nonceStr = UUID.randomUUID().toString();

		String resultStr = toResult(timeStamp, nonceStr, prepayId);

		//更新支付订单表
		orderPayParam.setPayOrderNo(orderPayRes.getPayOrderNo());
		orderPayParam.setPayType("2");//微信
		orderPayParam.setThirdPayStr(JSONObject.toJSONString(unifiedOrderReqData)+"<==>"+JSONObject.toJSONString(resultResp));
		orderPayParam.setModifyTime(DateUtil.getNowDate());

		orderPayDao.update(orderPayParam);

		return resultStr;
	}

	private String toResult(String timeStamp,String nonceStr,String prepayId) throws Exception{
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("appid", Configure.getAppid());
		map.put("timestamp", timeStamp);
		map.put("noncestr",nonceStr);
		map.put("package", "Sign=WXPay");
		map.put("prepayid", prepayId);
		map.put("partnerid", Configure.getMchid());
		map.put("sign", Signature.getSign(map));
		String str = "<xml><appid>"+Configure.getAppid()+"</appid>" +
				"<noncestr>"+nonceStr+"</noncestr>" +
				"<package>Sign=WXPay</package>" +
				"<partnerid>"+Configure.getMchid()+"</partnerid>" +
				"<prepayid>"+prepayId+"</prepayid>" +
				"<sign><![CDATA["+map.get("sign")+"]]></sign>" +
				"<timestamp>"+timeStamp+"</timestamp>" +
				"</xml>";

		return str;
	}

	private String getTimeStr(int addHours){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		Calendar cal = Calendar.getInstance();
		if(addHours>0){
			cal.add(Calendar.HOUR, addHours);
		}
		return sdf.format(cal.getTime());
	}




}